package com.bicon.botu.mall.order.service.impl;


import com.alibaba.druid.support.json.JSONUtils;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.TypeReference;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.plugins.Page;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import com.baomidou.mybatisplus.toolkit.IdWorker;
import com.bicon.botu.core.base.common.BusinessException;
import com.bicon.botu.core.base.common.Constants;
import com.bicon.botu.core.base.common.entity.BaseResult;
import com.bicon.botu.core.base.common.utils.DateUtil;
import com.bicon.botu.mall.base.entity.DeliveryPoint;
import com.bicon.botu.mall.base.entity.LogisticsCompany;
import com.bicon.botu.mall.base.rpc.service.DeliveryPointRpcService;
import com.bicon.botu.mall.base.rpc.service.LogisticsCompanyRpcService;
import com.bicon.botu.mall.base.rpc.service.SystemConfigRpcService;
import com.bicon.botu.mall.order.cache.UserRedisOperator;
import com.bicon.botu.mall.order.common.CompleteEnum;
import com.bicon.botu.mall.order.common.ConfirmEnum;
import com.bicon.botu.mall.order.common.OrderConstans;
import com.bicon.botu.mall.order.common.OrderUtil;
import com.bicon.botu.mall.order.dto.*;
import com.bicon.botu.mall.order.entity.*;
import com.bicon.botu.mall.order.mapper.AfterSalesImagesMapper;
import com.bicon.botu.mall.order.mapper.AfterSalesRecordsMapper;
import com.bicon.botu.mall.order.mapper.OrderChildMapper;
import com.bicon.botu.mall.order.param.AfterSalesParam;
import com.bicon.botu.mall.order.service.*;
import com.bicon.botu.mall.order.thirdparty.kdniao.KdniaoApi;
import com.bicon.botu.mall.order.thirdparty.kdniao.dto.TrackItem;
import com.bicon.botu.mall.order.thirdparty.kdniao.dto.TrackResult;
import com.bicon.botu.third.provider.rpc.service.MessageRpcService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.io.FileUtils;
import org.apache.commons.lang.time.DateFormatUtils;
import org.apache.commons.lang3.StringUtils;
import org.jxls.common.Context;
import org.jxls.expression.JexlExpressionEvaluator;
import org.jxls.transform.Transformer;
import org.jxls.util.JxlsHelper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.lang.reflect.Type;
import java.math.BigDecimal;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

/**
 * <p>
 * 订单退款退货记录 服务实现类
 * </p>
 *
 * @author 李双喜
 * @since 2018-06-14
 */
@Service
@Slf4j
public class AfterSalesRecordsServiceImpl extends ServiceImpl<AfterSalesRecordsMapper, AfterSalesRecords> implements IAfterSalesRecordsService {
    @Autowired
    private IOrderChildService iOrderChildService;

    @Autowired
    private IAfterSalesImagesService iAfterSalesImagesService;

    @Autowired
    private IAfterSalesDetailsService iAfterSalesDetailsService;

    @Autowired
    private AfterSalesRecordsMapper afterSalesRecordsMapper;

    @Autowired
    private AfterSalesImagesMapper afterSalesImagesMapper;

    @Autowired
    private DeliveryPointRpcService deliveryPointRpcService ;

    @Autowired
    private IOrderDetailService iOrderDetailService;

    @Autowired
    private OrderChildMapper orderChildMapper;

    @Autowired
    private IOrderGoodsService iOrderGoodsService;
    @Autowired
    private UserRedisOperator userRedisOperator;

    @Autowired
    private LogisticsCompanyRpcService logisticsCompanyRpcService;

    @Autowired
    private MessageRpcService messageRpcService;

    @Value("${mall.order.sms.template_code.back_goods_accept}")
    private String backGoodsAcceptSmsTemplate;

    @Value("${mall.order.sms.template_code.back_goods_reject}")
    private String backGoodsRejectSmsTemplate;

    @Value("${mall.order.sms.template_code.received_goods}")
    private String receivedGoodsSmsTemplate;

    @Value("${mall.order.sms.template_code.back_money_accept}")
    private String backMoneyAcceptSmsTemplate;

    @Value("${mall.order.sms.template_code.back_money_reject}")
    private String backMoneyRejectSmsTemplate;

    @Value("${mall.order.signName}")
    private String signName;

    @Autowired
    private SystemConfigRpcService systemConfigRpcService;

    @Autowired
    KdniaoApi kdniaoApi;


    /**
     * 申请退货退款
     *
     * @param afterSalesParamJson 申请退货实体
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public String applyAfterSales(String afterSalesParamJson) {
        Type type = new TypeReference<AfterSalesParam>() {
        }.getType();
        AfterSalesParam afterSalesParam = JSONObject.parseObject(afterSalesParamJson, type);
        //查询分组订单下的子订单
        String[] orderChildIdsArray = afterSalesParam.getOrderChildIds().split(",");
        //检查商品是否已经申请过
        List<OrderChild> orderChildList = iOrderChildService.selectList(new EntityWrapper<OrderChild>()
                .eq("logic_delete", Constants.DEL_LOGIC_NORMAL).in("id", orderChildIdsArray).eq("quit_state", 1));
        if (CollectionUtils.isNotEmpty(orderChildList)) {
            throw new BusinessException("不能重复提交售后申请");
        }
        //校验是否重复申请
        judgingApplication(orderChildIdsArray);
        //查询子订单是否为同一个主订单
        List<OrderChild> setOrderChildList = iOrderChildService.selectList(new EntityWrapper<OrderChild>()
                .eq("logic_delete", Constants.DEL_LOGIC_NORMAL).in("id", orderChildIdsArray).eq("quit_state", 0));
        if (CollectionUtils.isEmpty(setOrderChildList)) {
            throw new BusinessException("子订单不存在");
        }
        List<String> setIds = setOrderChildList.stream().map(OrderChild::getMainOrderId).collect(Collectors.toList());
        Set<String> set = new HashSet<String>(setIds);
        if (set.size() > 1 || set.size() == 0) {
            throw new BusinessException("该订单不符");
        }
        //查询分组订单
        OrderGoods orderGoods = new OrderGoods().selectOne(new EntityWrapper<OrderGoods>()
                .eq("logic_delete", Constants.DEL_LOGIC_NORMAL).eq("id", setIds.get(0)));
        if (null == orderGoods) {
            throw new BusinessException("该订单不存在");
        }
        AfterSalesRecords afterSalesRecords = insertAfterSalesEntity(afterSalesParam, orderGoods);
        //退货主订单
        boolean records = afterSalesRecords.insert();
        //新增订单详细
        List<AfterSalesDetails> salesDetailsList = new ArrayList<AfterSalesDetails>();
        //查询订单商品详情
        List<OrderDetail> orderDetailList = iOrderDetailService.selectList(new EntityWrapper<OrderDetail>()
                .eq("logic_delete", Constants.DEL_LOGIC_NORMAL).in("child_order_id", orderChildIdsArray));
        if (CollectionUtils.isEmpty(orderDetailList)) {
            throw new BusinessException("订单商品详情为空");
        }
        Map<String, String> mapChild = new HashMap<>();
        Map<String, BigDecimal> childMap = new HashMap<>(32);
        setOrderChildList.forEach(orderChild -> {
            childMap.put(orderChild.getId(), orderChild.getDiscountMoney());
        });
        //售后订单明细
        insertAfterSalesDetailsMethod(afterSalesRecords, salesDetailsList, orderDetailList, mapChild, childMap);
        //批量新增详情退货
        boolean detailResult = iAfterSalesDetailsService.insertBatch(salesDetailsList);
        //修改子订单
        setOrderChildList.forEach(orderChild -> {
            String afterSalesDetailsId = mapChild.get(orderChild.getId());
            orderChild.setOrderQuitId(afterSalesDetailsId);
            orderChild.setQuitState(1);
            orderChild.setAfterSaleRecordId(afterSalesRecords.getId());
            orderChild.preUpdate();
        });
        boolean childResult = iOrderChildService.updateBatchById(setOrderChildList);
        //如果上传图片，则新增图片
        List<AfterSalesImages> salesImagesList = new ArrayList<>();
        boolean imageResult = isImageResult(afterSalesParam, afterSalesRecords, salesImagesList);
        //新增售后记录操作信息
        boolean historyResult = insertOptHistoryMethod(afterSalesRecords, 1);
        if (records && detailResult && childResult && imageResult && historyResult) {
            return afterSalesRecords.getId();
        }
        return null;
    }


    /**
     * 检查商品是否已经申请过
     *
     * @param orderChildIdsArray
     */
    private void judgingApplication(String[] orderChildIdsArray) {
        List<AfterSalesDetails> detailsList = iAfterSalesDetailsService.selectList(new EntityWrapper<AfterSalesDetails>().eq("logic_delete", Constants.DEL_LOGIC_NORMAL).in("order_child_id", orderChildIdsArray));
        List<String> afterRecordIds = detailsList.stream().map(AfterSalesDetails::getAfterSalesRecordId).collect(Collectors.toList());
        if (CollectionUtils.isNotEmpty(afterRecordIds)) {
            List<Integer> integerList = new ArrayList<>();
            integerList.add(2);
            integerList.add(3);
            integerList.add(4);
            integerList.add(5);
            integerList.add(1);
            List<AfterSalesRecords> recordsList = this.selectList(new EntityWrapper<AfterSalesRecords>()
                    .in("id", afterRecordIds)
                    .eq("logic_delete", Constants.DEL_LOGIC_NORMAL)
                    .in("status", integerList));
            if (CollectionUtils.isNotEmpty(recordsList)) {
                throw new BusinessException("不能重复提交申请");
            }
        }
    }

    /**
     * 新增售后记录实体
     *
     * @param afterSalesParam
     * @param orderGoods
     * @return
     */
    private AfterSalesRecords insertAfterSalesEntity(AfterSalesParam afterSalesParam, OrderGoods orderGoods) {
        AfterSalesRecords afterSalesRecords = new AfterSalesRecords();
        afterSalesRecords.setApplyNo(OrderUtil.getOrderNo());
        afterSalesRecords.setApplyTime(new Date());
        afterSalesRecords.setUserId(orderGoods.getUserId());
        if (StringUtils.isNotEmpty(afterSalesParam.getDescriptionRemark())) {
            afterSalesRecords.setDescription(afterSalesParam.getDescriptionRemark());
        }
        afterSalesRecords.setOrderGoodsId(orderGoods.getId());
        afterSalesRecords.setPayBackMoneyWay(orderGoods.getPayWay());
        afterSalesRecords.setReason(afterSalesParam.getReason());
        afterSalesRecords.setStoreId(orderGoods.getStoreId());
        afterSalesRecords.setStatus(1);
        afterSalesRecords.setType(afterSalesParam.getType());
        afterSalesRecords.setPayBackFreight(1);
        //调用方法计算退费金额和运费
        Map<String, BigDecimal> map = this.calcPayBackAmount(afterSalesParam.getOrderChildIds());
        afterSalesRecords.setPayBackAmount(map.get("totalPayMoney"));
        afterSalesRecords.setOrderGoodsNo(orderGoods.getOrderGoodsNo());
        afterSalesRecords.setGoodsReceived(afterSalesParam.getGoodsReceived());
        afterSalesRecords.setPayBackFreightAmount(map.get("totalFreight"));
        afterSalesRecords.setPayBackAmountCalc(map.get("totalPayMoney"));
        afterSalesRecords.preInsert();
        return afterSalesRecords;
    }

    /**
     * 计算退费金额
     *
     * @param orderChildIds 多个子订单id  逗号隔开
     * @return
     */
    @Override
    public Map<String, BigDecimal> calcPayBackAmount(String orderChildIds) {
        Map<String, BigDecimal> decimalMap = new HashMap<>(6);
        String[] orderChildIdsArray = orderChildIds.split(",");
        //查询一个店铺中退货的子订单
        List<OrderChild> childList = iOrderChildService.selectList(new EntityWrapper<OrderChild>()
                .in("id", orderChildIdsArray).eq("logic_delete", Constants.DEL_LOGIC_NORMAL));
        if (CollectionUtils.isEmpty(childList)) {
            throw new BusinessException("订单不存在");
        }
        //遍历子订单，计算退费金额
        BigDecimal totalPayMoney = childList.stream().map(OrderChild::getPayMoney).reduce(BigDecimal.ZERO, BigDecimal::add);
        decimalMap.put("totalPayMoney", totalPayMoney);
        //含运费
        BigDecimal totalFreight = childList.stream().map(OrderChild::getFreight).reduce(BigDecimal.ZERO, BigDecimal::add);

        decimalMap.put("totalFreight", totalFreight);
        //最多
        decimalMap.put("maximum", totalPayMoney);
        return decimalMap;
    }

    @Override
    public Page<AfterSalesItemDto> getAfterSalesPageByCondition
            (Page<AfterSalesItemDto> page, Map<String, String> params) {
        List<AfterSalesItemDto> list = this.afterSalesRecordsMapper.getAfterSalesPageByCondition(page, params);
        /**
         * 售后状态处理：
         * 退款类型为1(仅退款)时，将status=2（商家已处理）的做为已退款状态
         * 退款类型为2（退款退货）时，将状态为4（已收货）的记录做为已退款状态
         */
        for (int i = 0; i < list.size(); i++) {
            if ((list.get(i).getType() == 1 && list.get(i).getStatus() == 2) ||
                    (list.get(i).getType() == 2 && list.get(i).getStatus() == 4)) {
                list.get(i).setStatus(5);
            }
        }

        page.setRecords(list);
        return page;
    }

    @Override
    public List<AfterSalesStatisticsDto> statisticAfterSale(String storeId) {
        List<AfterSalesStatistics> statistics = this.afterSalesRecordsMapper.statisticAfterSale(storeId);
        // 全部的数量
        Long all = 0L;
        // 未处理
        Long preProcess = 0L;
        // 处理中的数量
        Long processing = 0L;
        // 已完成
        Long processed = 0L;
        // 已拒绝
        Long rejected = 0L;
        // 已撤销
        Long canceled = 0L;

        for (int i = 0; i < statistics.size(); i++) {
            if (statistics.get(i).getType() == 1) {
                switch (statistics.get(i).getStatus()) {
                    case 1:
                        preProcess += statistics.get(i).getCount();
                        break;
                    case 2:
                        processed += statistics.get(i).getCount();
                        break;
                    case 5:
                        processed += statistics.get(i).getCount();
                        break;
                    case 6:
                        rejected += statistics.get(i).getCount();
                        break;
                    case 7:
                        canceled += statistics.get(i).getCount();
                        break;
                }
            } else {
                switch (statistics.get(i).getStatus()) {
                    case 1:
                        preProcess += statistics.get(i).getCount();
                        break;
                    case 2:
                        processing += statistics.get(i).getCount();
                        break;
                    case 3:
                        processing += statistics.get(i).getCount();
                        break;
                    case 4:
                        processed += statistics.get(i).getCount();
                        break;
                    case 5:
                        processed += statistics.get(i).getCount();
                        break;
                    case 6:
                        rejected += statistics.get(i).getCount();
                        break;
                    case 7:
                        canceled += statistics.get(i).getCount();
                        break;
                }
            }
            all += statistics.get(i).getCount();
        }
        List<AfterSalesStatisticsDto> result = new ArrayList<>();
        result.add(new AfterSalesStatisticsDto(0, all));
        result.add(new AfterSalesStatisticsDto(1, preProcess));
        result.add(new AfterSalesStatisticsDto(2, processing));
        result.add(new AfterSalesStatisticsDto(5, processed));
        result.add(new AfterSalesStatisticsDto(6, rejected));
        result.add(new AfterSalesStatisticsDto(7, canceled));

        return result;
    }

    @Override
    public AfterSalesForWebDto queryAfterSalesRecords(String afterSalesId) {
        AfterSalesForWebDto result = this.afterSalesRecordsMapper.queryAfterSalesRecordsForWeb(afterSalesId);
        List<String> images = this.afterSalesImagesMapper.queryImagesUrlByAfterSalesId(afterSalesId);
        result.setImages(images);
        return result;
    }

    @Override
    public Page<AfterSalesDetailsDto> queryAfterSalesGoodsList(String afterSalesId, Integer pageNo, Integer pageSize) {
        Page<AfterSalesDetailsDto> page = new Page<AfterSalesDetailsDto>(pageNo, pageSize);
        page.setOrderByField("create_date");
        page.setAsc(false);
        page.setRecords(this.afterSalesRecordsMapper.queryAfterSalesGoodsList(page, afterSalesId));
        return page;
    }

    /**
     * 撤销申请售后
     *
     * @param id 申请售后id
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public String forRepeal(String id) {
        AfterSalesRecords afterSalesRecords = this.selectOne(new EntityWrapper<AfterSalesRecords>()
                .eq("logic_delete", Constants.DEL_LOGIC_NORMAL).eq("id", id));
        if (null == afterSalesRecords) {
            throw new BusinessException("该售后申请不存在");
        }
        afterSalesRecords.setCancelTime(new Date());
        afterSalesRecords.setStatus(7);
        afterSalesRecords.preUpdate();
        Boolean result = afterSalesRecords.updateById();

        List<AfterSalesDetails> salesDetailsList = new AfterSalesDetails().selectList(new EntityWrapper<AfterSalesDetails>()
                .eq("logic_delete", Constants.DEL_LOGIC_NORMAL).eq("after_sales_record_id", id));
        List<String> childList = salesDetailsList.stream().map(AfterSalesDetails::getOrderChildId).collect(Collectors.toList());
        List<OrderChild> orderChildList = iOrderChildService.selectList(new EntityWrapper<OrderChild>()
                .eq("logic_delete", Constants.DEL_LOGIC_NORMAL).in("id", childList));
        orderChildList.forEach(orderChild -> {
            orderChild.setQuitState(0);
            orderChild.preUpdate();
        });
        Boolean resultChild = iOrderChildService.updateBatchById(orderChildList);
        //新增售后记录操作信息
        boolean historyResult = insertOptHistoryMethod(afterSalesRecords, 7);
        if (result && resultChild && historyResult) {
            return id;
        }
        return null;
    }

    /**
     * 修改申请
     *
     * @param afterSalesParamJson 售后订单json
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public String modifyAfterSales(String afterSalesParamJson) {
        Type type = new TypeReference<AfterSalesParam>() {
        }.getType();
        AfterSalesParam afterSalesParam = JSONObject.parseObject(afterSalesParamJson, type);
        if (StringUtils.isEmpty(afterSalesParam.getAfterSalesId())) {
            throw new BusinessException("申请订单id不能为空");
        }
        AfterSalesRecords afterSalesRecords = this.selectOne(new EntityWrapper<AfterSalesRecords>().eq("logic_delete", Constants.DEL_LOGIC_NORMAL).eq("id", afterSalesParam.getAfterSalesId()));
        if (null == afterSalesRecords) {
            throw new BusinessException("申请订单不存在");
        }
        afterSalesRecords.setGoodsReceived(afterSalesParam.getGoodsReceived());
        if (StringUtils.isNotEmpty(afterSalesParam.getReason())) {
            afterSalesRecords.setReason(afterSalesParam.getReason());
        } else {
            afterSalesRecords.setReason("");
        }
        if (StringUtils.isNotEmpty(afterSalesParam.getDescriptionRemark())) {
            afterSalesRecords.setDescription(afterSalesParam.getDescriptionRemark());
        }
        Map<String, BigDecimal> map = this.calcPayBackAmount(afterSalesParam.getOrderChildIds());
        afterSalesRecords.setPayBackFreightAmount(map.get("totalFreight"));
        afterSalesRecords.setPayBackAmountCalc(map.get("totalPayMoney"));
        afterSalesRecords.preUpdate();
        Boolean record = afterSalesRecords.updateById();
        List<AfterSalesDetails> detailsList = iAfterSalesDetailsService.selectList(new EntityWrapper<AfterSalesDetails>()
                .eq("logic_delete", Constants.DEL_LOGIC_NORMAL).eq("after_sales_record_id", afterSalesParam.getAfterSalesId()));
        for (AfterSalesDetails afterSalesDetails : detailsList) {
            afterSalesDetails.preDelete();
        }
        Boolean detail = iAfterSalesDetailsService.updateBatchById(detailsList);


        //查询分组订单下的子订单
        String[] orderChildIdsArray = afterSalesParam.getOrderChildIds().split(",");

        List<AfterSalesDetails> salesDetailsList = new ArrayList<AfterSalesDetails>();

        List<OrderChild> orderChildList = iOrderChildService.selectList(new EntityWrapper<OrderChild>()
                .eq("logic_delete", Constants.DEL_LOGIC_NORMAL).in("id", orderChildIdsArray));

        List<OrderDetail> orderDetailList = iOrderDetailService.selectList(new EntityWrapper<OrderDetail>()
                .eq("logic_delete", Constants.DEL_LOGIC_NORMAL).in("child_order_id", orderChildIdsArray));
        if (CollectionUtils.isEmpty(orderDetailList)) {
            throw new BusinessException("订单商品详情为空");
        }

        Map<String, String> mapChild = new HashMap<>();
        Map<String, BigDecimal> childMap = new HashMap<>(32);

        orderChildList.forEach(orderChild -> {
            childMap.put(orderChild.getId(), orderChild.getDiscountMoney());
        });

        //售后订单明细
        insertAfterSalesDetailsMethod(afterSalesRecords, salesDetailsList, orderDetailList, mapChild, childMap);
        //批量新增详情退货
        boolean detailResult = iAfterSalesDetailsService.insertBatch(salesDetailsList);


        List<String> childList = detailsList.stream().map(AfterSalesDetails::getOrderChildId).collect(Collectors.toList());
        List<OrderChild> orderChildren = iOrderChildService.selectList(new EntityWrapper<OrderChild>()
                .eq("logic_delete", Constants.DEL_LOGIC_NORMAL).in("id", childList));
        orderChildren.forEach(orderChild -> {
            orderChild.setQuitState(0);
            orderChild.preUpdate();
        });
        Boolean resultChild = iOrderChildService.updateBatchById(orderChildList);

        //修改子订单
        orderChildList.forEach(orderChild -> {
            String afterSalesDetailsId = mapChild.get(orderChild.getId());
            orderChild.setOrderQuitId(afterSalesDetailsId);
            orderChild.preUpdate();
        });


        orderChildList.forEach(orderChild -> {
            String afterSalesDetailsId = mapChild.get(orderChild.getId());
            orderChild.setOrderQuitId(afterSalesDetailsId);
            orderChild.preUpdate();
        });
        boolean childResult = iOrderChildService.updateBatchById(orderChildList);

        List<AfterSalesImages> salesImagesList = iAfterSalesImagesService.selectList(new EntityWrapper<AfterSalesImages>()
                .eq("logic_delete", Constants.DEL_LOGIC_NORMAL).in("after_sales_record_id", afterSalesParam.getAfterSalesId()));
        Boolean selectImages = false;
        if (CollectionUtils.isNotEmpty(salesImagesList)) {
            salesImagesList.forEach(afterSalesImages -> {
                afterSalesImages.preDelete();
            });
            selectImages = iAfterSalesImagesService.updateBatchById(salesImagesList);
        } else {
            selectImages = true;
        }
        boolean imageResult;
        List<AfterSalesImages> salesImages = new ArrayList<>();
        imageResult = isImageResult(afterSalesParam, afterSalesRecords, salesImages);

        //新增售后记录操作信息
        Boolean historyResult = insertOptHistoryMethod(afterSalesRecords, 6);
        if (record && detailResult && childResult && imageResult && historyResult && selectImages && detail && resultChild) {
            return afterSalesRecords.getId();
        }
        return null;
    }

    /**
     * 新增操作记录
     *
     * @param afterSalesRecords 售后记录实体
     * @param i
     * @return
     */
    private Boolean insertOptHistoryMethod(AfterSalesRecords afterSalesRecords, Integer i) {
        AfterSalesOptHistory afterSalesOptHistory = new AfterSalesOptHistory();
        afterSalesOptHistory.setAfterSalesRecordId(afterSalesRecords.getId());
        afterSalesOptHistory.setOptDate(new Date());
        afterSalesOptHistory.setOptType(i);
        afterSalesOptHistory.setUserId(afterSalesRecords.getUserId());
        afterSalesOptHistory.preInsert();
        return  afterSalesOptHistory.insert();
    }

    /**
     * 退货发货单填写
     *
     * @param id                   申请退款id
     * @param deliveryPointId      物流公司id
     * @param logisticsCode        运单号
     * @param logisticsDescription 物流描述
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean commitLogistics(String id, String deliveryPointId, String logisticsCode, String logisticsDescription) {
        BaseResult<LogisticsCompany> logisticsCompanyBaseResult = logisticsCompanyRpcService.enabledList(deliveryPointId);
        if (logisticsCompanyBaseResult.getCode() != Constants.RESPONSE_CODE_200) {
            log.error("调用远程RPC查询发货点信息失败：{} ：{}", logisticsCompanyBaseResult.getCode(), logisticsCompanyBaseResult.getMessage());
            throw new BusinessException(Constants.RESPONSE_CODE_500, Constants.RESPONSE_MESSAGE_500);
        }
        LogisticsCompany logisticsCompany = logisticsCompanyBaseResult.getData();
        AfterSalesRecords afterSalesRecords = this.selectOne(new EntityWrapper<AfterSalesRecords>().eq("logic_delete", Constants.DEL_LOGIC_NORMAL).eq("id", id));
        if (null == afterSalesRecords) {
            throw new BusinessException("申请订单不存在");
        }
        afterSalesRecords.setLogisticsCompanyId(logisticsCompany.getId());
        afterSalesRecords.setLogisticsCompanyName(logisticsCompany.getName());
        afterSalesRecords.setLogisticsCompanyPhone(logisticsCompany.getPhone());
        afterSalesRecords.setLogisticsCompanyCode(logisticsCompany.getCode());
        afterSalesRecords.setLogisticsCode(logisticsCode);
        afterSalesRecords.setStatus(3);
        if (StringUtils.isNotEmpty(logisticsDescription)) {
            afterSalesRecords.setLogisticsDescription(logisticsDescription);
        }
        afterSalesRecords.preUpdate();
        return afterSalesRecords.updateById();
    }

    private boolean isImageResult(AfterSalesParam afterSalesParam, AfterSalesRecords
            afterSalesRecords, List<AfterSalesImages> salesImages) {
        boolean imageResult;
        if (CollectionUtils.isNotEmpty(afterSalesParam.getImages())) {
            int i = 1;
            for (String img : afterSalesParam.getImages()) {
                AfterSalesImages afterSalesImages = new AfterSalesImages();
                afterSalesImages.setAfterSalesRecordId(afterSalesRecords.getId());
                afterSalesImages.setImageUrl(img);
                afterSalesImages.setSort(i);
                afterSalesImages.preInsert();
                salesImages.add(afterSalesImages);
                i++;
            }
            imageResult = iAfterSalesImagesService.insertBatch(salesImages);
        } else {
            imageResult = true;
        }
        return imageResult;
    }


    private void insertAfterSalesDetailsMethod(AfterSalesRecords
                                                       afterSalesRecords, List<AfterSalesDetails> salesDetailsList, List<OrderDetail> orderDetailList, Map<String, String> mapChild, Map<String, BigDecimal> childMap) {
        orderDetailList.forEach(orderDetail -> {
            AfterSalesDetails afterSalesDetails = new AfterSalesDetails();
            afterSalesDetails.setAfterSalesRecordId(afterSalesRecords.getId());
            afterSalesDetails.setGoodsId(orderDetail.getGoodsId());
            afterSalesDetails.setGoodsName(orderDetail.getGoodsName());
            afterSalesDetails.setGoodsNumber(orderDetail.getGoodsNumber());
            afterSalesDetails.setGoodsType(Integer.valueOf(orderDetail.getGoodsType()));
            afterSalesDetails.setOrderChildId(orderDetail.getChildOrderId());
            afterSalesDetails.setSkuImage(orderDetail.getItemImage());
            afterSalesDetails.setSkuName(orderDetail.getSkuName());
            afterSalesDetails.setPlatformPrice(orderDetail.getGoodsPlatformPrice());
            BigDecimal discount = childMap.get(orderDetail.getChildOrderId());
            Double total = orderDetail.getGoodsPlatformPrice().doubleValue() * orderDetail.getGoodsNumber();
            BigDecimal bigDecimal = new BigDecimal(total);
            afterSalesDetails.setPayBackAmount(bigDecimal.subtract(discount));
            afterSalesDetails.preInsert();
            salesDetailsList.add(afterSalesDetails);
            mapChild.put(orderDetail.getChildOrderId(), afterSalesDetails.getId());
        });
    }


    /**
     * 根据id查询详情
     *
     * @param id 申请售后id
     * @return
     */
    @Override
    public AfterSaleDetailDto forDetails(String id) throws ParseException {
        AfterSaleDetailDto afterSaleDetailDto = new AfterSaleDetailDto();
        AfterSalesRecords afterSalesRecords = this.selectOne(new EntityWrapper<AfterSalesRecords>()
                .eq("logic_delete", Constants.DEL_LOGIC_NORMAL).eq("id", id));
        if (null == afterSalesRecords) {
            throw new BusinessException("该售后申请不存在");
        }
        //通过申请售后id,来查询售后每件商品是否已经被申请
        List<AfterSalesDetails> afterSalesDetailsList = iAfterSalesDetailsService.selectList(new EntityWrapper<AfterSalesDetails>().eq("logic_delete", Constants.DEL_LOGIC_NORMAL).eq("after_sales_record_id", id));
        //获取其中的子订单id
        List<String> orderChildIds = afterSalesDetailsList.stream().map(AfterSalesDetails::getOrderChildId).collect(Collectors.toList());
        List<OrderChild> childList = iOrderChildService.selectList(new EntityWrapper<OrderChild>()
                .eq("logic_delete", Constants.DEL_LOGIC_NORMAL).in("id", orderChildIds));
        Map<String, OrderChild> orderChildMap = childList.stream().collect(Collectors.toMap(OrderChild::getId, a -> a, (k1, k2) -> k1));
        afterSaleDetailDto.setAfterSalesId(id);
        OrderGoods orderGoods = iOrderGoodsService.selectOne(new EntityWrapper<OrderGoods>().eq("logic_delete", Constants.DEL_LOGIC_NORMAL).eq("id", afterSalesRecords.getOrderGoodsId()));
        setAfterSaleDetailDto(afterSaleDetailDto, afterSalesRecords, orderGoods);
        if (StringUtils.isNotEmpty(afterSalesRecords.getDescription())) {
            afterSaleDetailDto.setDescriptionRemark(afterSalesRecords.getDescription());
        }
        afterSaleDetailDto.setOrderGoodsNo(afterSalesRecords.getOrderGoodsNo());
        afterSaleDetailDto.setPayBackAmount(afterSalesRecords.getPayBackAmount());
        afterSaleDetailDto.setReason(afterSalesRecords.getReason());
        if (afterSalesRecords.getStatus() == 1) {
            Integer i = systemSettings(OrderConstans.AFTER_SALE);
            if (i > 0) {
                Date create = afterSalesRecords.getCreateDate();
                String dateScope = getRemainingTime(create, i);
                afterSaleDetailDto.setLimitDate("剩余" + dateScope);
            }
            afterSaleDetailDto.setSlogan("您已成功发起退货申请，请耐心等待商家处理。");
        } else if (afterSalesRecords.getStatus() == 2) {
            if (afterSalesRecords.getType() == 2) {
                Date create = afterSalesRecords.getCreateDate();
                String dateScope = getRemainingTime(create, 7);
                afterSaleDetailDto.setLimitDate("剩余" + dateScope);
                afterSaleDetailDto.setSlogan("客服已经处理了您的退货退款申请，请在规定时间内填写退货单号尽快发货，超时退款申请将取消，如没解决问题，您可重复发起申请退款");
                AfterSaleDetailDto.AddressDetail addressDetail = new AfterSaleDetailDto.AddressDetail();
                if (StringUtils.isNotEmpty(afterSalesRecords.getDeliveryShipper())) {
                    addressDetail.setName(afterSalesRecords.getDeliveryTelephone());
                }
                if (StringUtils.isNotEmpty(afterSalesRecords.getDeliveryTelephone())) {
                    addressDetail.setPhone(afterSalesRecords.getDeliveryTelephone());
                }
                if (StringUtils.isNotEmpty(afterSalesRecords.getDeliveryAddress())) {
                    addressDetail.setAddressDetail(afterSalesRecords.getDeliveryAddress());
                }
                afterSaleDetailDto.setAddressDetail(addressDetail);
            } else if (afterSalesRecords.getType() == 1) {
                afterSaleDetailDto.setStatus(5);
                afterSaleDetailDto.setLimitDate(DateFormatUtils.format(afterSalesRecords.getBackTime(),"yyyy-MM-dd HH:mm"));
                afterSaleDetailDto.setSlogan("您的退款已经原路返回到你的支付账户中，请注意查收，如遇到问题请联系客服");
            }
        } else if (afterSalesRecords.getStatus() == 3) {
            //物流
            if (afterSalesRecords.getType() == 2) {
                OrderLogisticsDto orderLogisticsDto = this.getLogistics(id);
                if (null != orderLogisticsDto && CollectionUtils.isNotEmpty(orderLogisticsDto.getTraces())) {
                    List<TrackItem> trackItemList = orderLogisticsDto.getTraces();
                    TrackItem trackItem = trackItemList.get(0);
                    LogisticsDto logisticsDto = new LogisticsDto();
                    logisticsDto.setLogistics(trackItem.getAcceptStation());
                    logisticsDto.setDate(trackItem.getAcceptTime());
                    afterSaleDetailDto.setOrderLogisticsDto(logisticsDto);
                }
            }
            //时间
            Integer i = systemSettingsDeliver(OrderConstans.AFTER_SALE_AFFIRM);
            if (i > 0) {
                Date create = afterSalesRecords.getCreateDate();
                String dateScope = getRemainingTime(create, i);
                afterSaleDetailDto.setLimitDate("剩余" + dateScope);
            }
        } else if (afterSalesRecords.getStatus() == 5 || afterSalesRecords.getStatus() == 4) {
            afterSaleDetailDto.setLimitDate(DateFormatUtils.format(afterSalesRecords.getBackTime(),"yyyy-MM-dd HH:mm"));
            afterSaleDetailDto.setSlogan("您的退款已经原路返回到你的支付账户中，请注意查收，如遇到问题请联系客服");
        } else if (afterSalesRecords.getStatus() == 6) {
            afterSaleDetailDto.setLimitDate(DateFormatUtils.format(afterSalesRecords.getProcessTime(),"yyyy-MM-dd HH:mm"));
            afterSaleDetailDto.setSlogan(afterSalesRecords.getRejectReason());
        } else if (afterSalesRecords.getStatus() == 7) {
            afterSaleDetailDto.setLimitDate(DateFormatUtils.format(afterSalesRecords.getCancelTime(),"yyyy-MM-dd HH:mm"));
            afterSaleDetailDto.setSlogan("您已撤销本次退款申请，如问题仍未解决，您可以重新发起申请");
        }
        List<AfterSalesDetails> salesDetailsList = new AfterSalesDetails().selectList(new EntityWrapper<AfterSalesDetails>()
                .eq("logic_delete", Constants.DEL_LOGIC_NORMAL).in("after_sales_record_id", id));
        List<AfterSaleDetailDto.ShopListBean> listBeans = new ArrayList<>();
        for (AfterSalesDetails afterSalesDetails : salesDetailsList) {
            setShopListBean(listBeans, afterSalesDetails, orderChildMap);
        }
        //查询图片集
        List<AfterSalesImages> detailsList = iAfterSalesImagesService.selectList(new EntityWrapper<AfterSalesImages>()
                .eq("logic_delete", Constants.DEL_LOGIC_NORMAL).in("after_sales_record_id", id).orderBy("sort", true));
        List<String> urlList = detailsList.stream().map(AfterSalesImages::getImageUrl).collect(Collectors.toList());
        afterSaleDetailDto.setImageUrl(urlList);
        afterSaleDetailDto.setShopList(listBeans);
        return afterSaleDetailDto;
    }

    /**
     * 自动售后处理-调用系统设置是否开启和关闭功能项（开启提示时间）
     */
    public Integer systemSettings(String source) {
        BaseResult baseResult = systemConfigRpcService.getOderConfigValue(source);
        if (baseResult.getCode() == Constants.RESPONSE_CODE_200) {
            MallConfigDto mallConfigDto = JSONObject.parseObject(JSONObject.toJSONString(baseResult.getData()), MallConfigDto.class);
            return CompleteEnum.valueOf(mallConfigDto.getDictionaryValue()).getTimeLength();
        }
        return null;
    }

    public Integer systemSettingsDeliver(String source) {
        BaseResult baseResult = systemConfigRpcService.getOderConfigValue(source);
        if (baseResult.getCode() == Constants.RESPONSE_CODE_200) {
            MallConfigDto mallConfigDto = JSONObject.parseObject(JSONObject.toJSONString(baseResult.getData()), MallConfigDto.class);
            return ConfirmEnum.valueOf(mallConfigDto.getDictionaryValue()).getTimeLength();
        }
        return null;
    }


    /**
     * 设置afterSaleDetailDto值
     *
     * @param afterSaleDetailDto
     * @param afterSalesRecords
     * @param orderGoods
     */
    private void setAfterSaleDetailDto(AfterSaleDetailDto afterSaleDetailDto, AfterSalesRecords afterSalesRecords, OrderGoods orderGoods) {
        afterSaleDetailDto.setOrderGoodsId(afterSalesRecords.getOrderGoodsId());
        afterSaleDetailDto.setPayState(orderGoods.getPayState());
        afterSaleDetailDto.setType(afterSalesRecords.getType());
        afterSaleDetailDto.setGoodsReceived(afterSalesRecords.getGoodsReceived());
        afterSaleDetailDto.setStatus(afterSalesRecords.getStatus());
        afterSaleDetailDto.setApplyNo(afterSalesRecords.getApplyNo());
        afterSaleDetailDto.setContactWay("400-7675-8656");
        afterSaleDetailDto.setCreateDate(afterSalesRecords.getCreateDate());
    }

    /**
     * 设置商品属性
     *
     * @param listBeans
     * @param afterSalesDetails
     */
    private void setShopListBean(List<AfterSaleDetailDto.ShopListBean> listBeans,
                                 AfterSalesDetails afterSalesDetails, Map<String, OrderChild> orderChildMap) {
        AfterSaleDetailDto.ShopListBean shopListBean = new AfterSaleDetailDto.ShopListBean();
        shopListBean.setGoodsName(afterSalesDetails.getGoodsName());
        shopListBean.setNumber(afterSalesDetails.getGoodsNumber());
        shopListBean.setGoodsPlatformPrice(afterSalesDetails.getPlatformPrice());
        shopListBean.setCustomState(afterSalesDetails.getGoodsType());
        shopListBean.setMainPicture(afterSalesDetails.getSkuImage());
        shopListBean.setSkuName(afterSalesDetails.getSkuName());
        shopListBean.setOrderChildId(afterSalesDetails.getOrderChildId());
        shopListBean.setProductRepertoryId(afterSalesDetails.getGoodsId());
        //撤销过和拒绝和未申请，传入状态为0  其他传入为1
        OrderChild orderChild = orderChildMap.get(afterSalesDetails.getOrderChildId());
        shopListBean.setQuitState(orderChild.getQuitState());
        listBeans.add(shopListBean);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean approvalAfterSales(String afterSalesId, boolean approvalResult,
                                      boolean payBackFreight, BigDecimal payBackAmount,
                                      String deliveryPointId, Integer backDeliveryMethod, String rejectReason, String userId) {
        // 查询售后信息
        AfterSalesRecords records = new AfterSalesRecords();
        records = records.selectById(afterSalesId);
        if (records == null) {
            throw new BusinessException(Constants.RESPONSE_CODE_500, "未查询到售后申请记录");
        }
        AfterSalesRecords updateRecords = new AfterSalesRecords();
        updateRecords.setId(records.getId());

        //原本付邮费，更新为不付邮费时，PayBackAmountCalc减去邮费金额
        if (records.getPayBackFreight() == 1) {
            if (!payBackFreight) {
                updateRecords.setPayBackAmountCalc(records.getPayBackAmountCalc().subtract(records.getPayBackFreightAmount()));
                updateRecords.setPayBackFreight(0);
            }
        } else {
            //原本不付邮费，更新为付邮费时，PayBackAmountCalc加上邮费金额
            if (payBackFreight) {
                updateRecords.setPayBackAmountCalc(records.getPayBackAmountCalc().add(records.getPayBackFreightAmount()));
                updateRecords.setPayBackFreight(1);
            }
        }
        // 调用远程接口查询发货点信息
        if (StringUtils.isNotBlank(deliveryPointId)) {
            BaseResult<DeliveryPoint> deliveryPointListResult = deliveryPointRpcService.queryById(deliveryPointId);
            if (deliveryPointListResult.getCode() != Constants.RESPONSE_CODE_200) {
                log.error("调用远程RPC查询发货点信息失败：{} ：{}", deliveryPointListResult.getCode(), deliveryPointListResult.getMessage());
                throw new BusinessException(Constants.RESPONSE_CODE_500, Constants.RESPONSE_MESSAGE_500);
            }
            DeliveryPoint deliveryPoints = deliveryPointListResult.getData();
            updateRecords.setDeliveryPointId(deliveryPointId);
            updateRecords.setDeliveryShipper(deliveryPoints.getShipper());
            updateRecords.setDeliveryRegion(deliveryPoints.getRegion());
            updateRecords.setDeliveryAddress(deliveryPoints.getAddress());
            updateRecords.setDeliveryTelephone(deliveryPoints.getTelephone());
        }

        if (payBackAmount != null && payBackAmount.compareTo(BigDecimal.ZERO) > 0) {
            updateRecords.setPayBackAmount(payBackAmount);
        } else {
            updateRecords.setPayBackAmount(updateRecords.getPayBackAmountCalc());
        }
        updateRecords.setBackDeliveryMethod(backDeliveryMethod);
        if (StringUtils.isNotBlank(rejectReason)) {
            updateRecords.setRejectReason(rejectReason);
        }
        // 如果仅退款 且通过审核，则更新退款时间
        if (records.getType() == 1&&approvalResult) {
            updateRecords.setBackTime(new Date());
        }
        updateRecords.setStatus(approvalResult ? 2 : 6);
        updateRecords.setProcessTime(new Date());
        updateRecords.updateById();

        // 插入售后操作历史
        AfterSalesOptHistory history = new AfterSalesOptHistory();
        history.setId(IdWorker.get32UUID());
        history.setAfterSalesRecordId(afterSalesId);
        history.setOptDate(new Date());
        history.setUserId(userId);
        history.setOptType(approvalResult ? 2 : 5);
        history.insert();

        // 更新订单明细的quit_status
        this.orderChildMapper.batchUpdateQuitState(afterSalesId, approvalResult ? 1 : 0);
        // 发送消息
        String phone = userRedisOperator.getUserPhone(records.getUserId());
        if (StringUtils.isNotBlank(phone)) {
            List<String> listPhone = new ArrayList<>();
            listPhone.add(phone);
            List<Map<String, String>> params = new ArrayList<>();
            Map<String, String> param = new HashMap<>();
            String templateName = null;
            if (records.getType() == 1) {
                //退款受理短信
                if (approvalResult) {
                    templateName = this.backMoneyAcceptSmsTemplate;
                    param.put("afterSaleNo", records.getApplyNo());
                    param.put("money", updateRecords.getPayBackAmount().toString());
                } else {
                    //退款拒绝短信
                    templateName = this.backMoneyRejectSmsTemplate;
                    param.put("afterSaleNo", records.getApplyNo());
                }
            } else {
                //退货退款受理短信
                if (approvalResult) {
                    templateName = this.backGoodsAcceptSmsTemplate;
                    param.put("afterSaleNo", records.getApplyNo());
                } else {
                    //退货退款拒绝短信
                    templateName = this.backGoodsRejectSmsTemplate;
                    param.put("afterSaleNo", records.getApplyNo());
                }
            }
            params.add(param);
            messageRpcService.batchSendYunSms(JSONUtils.toJSONString(listPhone), JSONUtils.toJSONString(params), templateName, this.signName);
        }


        return true;
    }

    /**
     * 时间差计算
     *
     * @param dateCreate 最大时间
     * @param scope      范围（天数）
     * @return
     * @throws ParseException
     */
    public static String getRemainingTime(Date dateCreate, Integer scope) throws ParseException {
        Date createDay = DateUtil.addDay(dateCreate, scope);
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String big = sdf.format(new Date(Long.parseLong(String.valueOf(createDay.getTime()))));
        Date d1 = sdf.parse(big);
        Date d2 = sdf.parse(sdf.format(new Date()));
        long date = d1.getTime() - d2.getTime();
        long day = date / (1000 * 60 * 60 * 24);
        if (day < 0) {
            day = 0;
        }
        long hour = (date / (1000 * 60 * 60) - day * 24);
        if (hour < 0) {
            hour = 0;
        }
        long min = ((date / (60 * 1000)) - day * 24 * 60 - hour * 60);
        if (min < 0) {
            min = 0;
        }
        long s = (date / 1000 - day * 24 * 60 * 60 - hour * 60 * 60 - min * 60);
        if (s < 0) {
            s = 0;
        }
        return "" + day + "天" + hour + "小时" + min + "分";
    }

    @Override
    @Transactional
    public boolean receivedGoods(String userId, String afterSalesId) {
        AfterSalesRecords records = new AfterSalesRecords();
        records = records.selectById(afterSalesId);
        if (records != null && records.getStatus() == 3) {
            this.afterSalesRecordsMapper.receivedGoods(afterSalesId);

            AfterSalesOptHistory history = new AfterSalesOptHistory();
            history.setId(IdWorker.get32UUID());
            history.setAfterSalesRecordId(afterSalesId);
            history.setOptDate(new Date());
            history.setUserId(userId);
            history.setOptType(4);
            history.insert();

            // 发送消息
            String phone = userRedisOperator.getUserPhone(records.getUserId());
            if (StringUtils.isNotBlank(phone)) {
                List<String> listPhone = new ArrayList<>();
                listPhone.add(phone);
                List<Map<String, String>> params = new ArrayList<>();
                Map<String, String> param = new HashMap<>();
                param.put("afterSaleNo", records.getApplyNo());
                param.put("money", records.getPayBackAmount().toString());
                params.add(param);
                messageRpcService.batchSendYunSms(JSONUtils.toJSONString(listPhone), JSONUtils.toJSONString(params), this.receivedGoodsSmsTemplate, this.signName);
            }
            return true;
        } else {
            throw new BusinessException(Constants.RESPONSE_CODE_500, "当前售后申请状态不允许确认收货");
        }
    }

    @Override
    public void exportRecords(Map<String, String> params, HttpServletRequest request, HttpServletResponse response) {
        //查询售后申请记录
        List<AfterSalesExportDto> afterSalesExportDtoList = this.afterSalesRecordsMapper.getAfterSalesExportList(params);
        List<String> afterSalesIdList = new ArrayList<>();
        for (int i = 0; i < afterSalesExportDtoList.size(); i++) {
            afterSalesIdList.add(afterSalesExportDtoList.get(i).getAfterSalesId());
        }

        List<AfterSalesImages> imagesList = afterSalesImagesMapper.selectList(new EntityWrapper<AfterSalesImages>()
                .eq("logic_delete", 0).in("after_sales_record_id", afterSalesIdList));
        for (int i = 0; i < imagesList.size(); i++) {
            for (int j = 0; j < afterSalesExportDtoList.size(); j++) {
                if (afterSalesExportDtoList.get(j).getAfterSalesId().equals(imagesList.get(i).getAfterSalesRecordId())) {
                    if (afterSalesExportDtoList.get(j).getImages() == null) {
                        afterSalesExportDtoList.get(j).setImages(new ArrayList<String>());
                    }
                    afterSalesExportDtoList.get(j).getImages().add(imagesList.get(i).getImageUrl());
                    break;
                }
            }
        }
        InputStream stream = null;
        FileInputStream in = null;
        try {
            String templatePath = OrderConstans.EXCEL_TEMPLATE_BASE + File.separator + "after_sale_export_template.xls";
            stream = getClass().getClassLoader().getResourceAsStream(templatePath);
            File targetFile = new File("after_sale_export_template.xls");
            FileUtils.copyInputStreamToFile(stream, targetFile);
            in = new FileInputStream(targetFile);

            // 设定输出文件头与响应上下文类型
            String fileName = OrderGoodsServiceImpl.encodeFileName("售后申请列表.xls", request);
            response.setHeader("Content-disposition", "attachment; filename=" + fileName);
            response.setContentType("application/vnd.ms-excel");

            // 设置导出上下文内容
            Context context = new Context();
            context.putVar("afterSales", afterSalesExportDtoList);

            JxlsHelper jxlsHelper = JxlsHelper.getInstance();
            Transformer transformer = jxlsHelper.createTransformer(in, response.getOutputStream());
            JexlExpressionEvaluator evaluator = (JexlExpressionEvaluator) transformer.getTransformationConfig().getExpressionEvaluator();
            //添加自定义函数
            Map<String, Object> funcs = new HashMap<>();
            funcs.put("orderDto", new AfterSalesExportDto());
            evaluator.getJexlEngine().setFunctions(funcs);
            jxlsHelper.processTemplate(context, transformer);
            response.flushBuffer();
            //调用RPC上传文件到文件系统
        } catch (FileNotFoundException e) {
            log.error("文件未找到", e);
        } catch (IOException e) {
            log.error("导出售后申请记录失败", e);
        } finally {
            if (stream != null) {
                try {
                    stream.close();
                } catch (IOException e) {
                    log.error("导出售后申请关闭流失败", e);
                }
            }
            if (in != null) {
                try {
                    in.close();
                } catch (IOException e) {
                    log.error("导出售后申请关闭流失败", e);
                }
            }
        }
    }


    /**
     * 根据售后订单id，查询物流信息
     *
     * @param afterSalesId 申请售后id
     * @return
     */
    @Override
    public OrderLogisticsDto getLogistics(String afterSalesId) {
        AfterSalesRecords afterSalesRecords = this.selectOne(new EntityWrapper<AfterSalesRecords>()
                .eq("logic_delete", Constants.DEL_LOGIC_NORMAL).eq("id", afterSalesId));
        OrderLogistics orderLogistics = new OrderLogistics();
        orderLogistics.setLogisticsCode(afterSalesRecords.getLogisticsCode());
        orderLogistics.setLogisticsCompanyCode(afterSalesRecords.getLogisticsCompanyCode());
        orderLogistics.setLogisticsCompanyName(afterSalesRecords.getLogisticsCompanyName());
        orderLogistics.setLogisticsCompanyPhone(afterSalesRecords.getLogisticsCompanyPhone());
        orderLogistics.setOrderId(afterSalesId);
        if (orderLogistics == null) {
            throw new BusinessException(Constants.RESPONSE_CODE_500, "订单物流信息查询失败");
        }
        TrackResult trackResult = null;
        try {
            trackResult = this.kdniaoApi.getOrderTracesByJson(orderLogistics.getLogisticsCompanyCode(), orderLogistics.getLogisticsCode());
        } catch (Exception e) {
            throw new BusinessException(Constants.RESPONSE_CODE_500, "调用第三方API查询物流信息失败");
        }
        OrderLogisticsDto result = new OrderLogisticsDto();
        result.setLogisticsCompanyName(orderLogistics.getLogisticsCompanyName());
        result.setLogisticsCompanyPhone(orderLogistics.getLogisticsCompanyPhone());
        result.setLogisticsCode(orderLogistics.getLogisticsCode());
        Collections.reverse(trackResult.getTraces());
        result.setTraces(trackResult.getTraces());


        for (int i = 0; i < result.getTraces().size(); i++) {
            result.getTraces().get(i).setAcceptTime(result.getTraces().get(i).getAcceptTime().replaceAll("/", "-"));
        }

        return result;
    }

}
